import { Plugin } from '@ckeditor/ckeditor5-core'
import { ClipboardPipeline } from '@ckeditor/ckeditor5-clipboard'
import juice from 'juice'

/*
匹配 excel

excel 粘贴时 获取的 html 中 存在以下标识
<html
 xmlns:v="urn:schemas-microsoft-com:vml"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
>

<meta name=Generator content="Microsoft Excel">
* */
const EXCEL_MARK_REG1 = /<meta\s*name="?generator"?\s*content="?microsoft\s*excel\s*\d+"?\/?>/i
const EXCEL_MARK_REG2 = /xmlns:x="urn:schemas-microsoft-com:office:excel/i
// 匹配 table
const TABLE_REG = /<table[^>]*>[\s\S]*<\/table>/i
// 匹配 td style padding
const TD_PADDING_REG = /(?<=(td[\r\n\t]*{[^}]*))(padding-(top|left|right):1px;)(?=[^}]*})/ig
// 匹配 table style width
const TABLE_WIDTH_REG = /(?<=<table[^>]*style=[^>]*)(width:[\d.]+pt;?)(?=[^>]*>)/ig

/*
* 判断是否是从 excel 粘贴
* @params {string} htmlString - HTML 字符串
* @return {boolean}
* */
function isActive(htmlString) {
  return EXCEL_MARK_REG1.test(htmlString) || EXCEL_MARK_REG2.test(htmlString)
}

/*
* 处理 excel 粘贴的 HTML string
* @params {string} htmlString - HTML 字符串
* @return {string}
* 1. 添加 内联样式
* 2. 返回 table HTML string
* */
function excelHtmlHandle(htmlString) {
  if (!TABLE_REG.test(htmlString)) {
    return ''
  }

  htmlString = htmlString
    .replace(TD_PADDING_REG, '') // 删除 td padding - 避免单元格四周内边距不一致（EXCEL粘贴时默认有上左右方向边距）
    .replace(TABLE_WIDTH_REG, '') // 删除 table style width - 避免单元格宽度无法正常调整

  // 将 class 样式 添加到 内联样式
  const inlineStyleHtml = juice(htmlString)

  const match = inlineStyleHtml.match(TABLE_REG)

  return match ? match[0] : ''
}

export default class PasteFromExcel extends Plugin {
  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
  static get pluginName() {
    return 'PasteFromExcel'
  }

  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
  static get requires() {
    return [ClipboardPipeline]
  }

  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
  init() {
    const { editor } = this

    editor.plugins.get('ClipboardPipeline').on(
      'inputTransformation',
      (evt, data) => {
        const htmlString = data.dataTransfer.getData('text/html')

        if (!isActive(htmlString)) {
          return
        }

        const tableHtmlString = excelHtmlHandle(htmlString)
        data.content = editor.data.htmlProcessor.toView(tableHtmlString)

        // 避免 PasteFromOffice 处理
        Object.assign(data, {
          _isTransformedWithPasteFromOffice: true
        })
      },
      { priority: 'highest' }
    )
  }
}
